package swym.server;

import swym.protocol.*;
import java.io.*;
import java.net.*;
import java.util.*;
import swym.protocol.server.MessageHandler;

public class ClientConnectionHandler extends Thread
{
    ObjectInputStream in;
    ObjectOutputStream out;
    ClientSocket clientSocket;
    
    User user;
    Client client;
    ClientConnection connection;
    
    private static final boolean DEBUG = true;
    
    public ClientConnectionHandler( Socket socket ) throws IOException 
    {
        this.clientSocket = new ClientSocket( socket );
        
        out = this.clientSocket.getOutputStream();
        in  = this.clientSocket.getInputStream();
        
        user = null;
        client = null;
        connection = null;
    }
            
    public void run()
    {
        try
        {
            connection = new ClientConnection( clientSocket.getSocket().getInetAddress(), 
                                               clientSocket.getSocket().getPort() );
            connection.setSocket( clientSocket );
            
            if ( DEBUG )
                Log.writeEntry( "new connection: " + connection.toString() );
            
            ActionMessage message = (ActionMessage) in.readObject();
            
            MessageHandler handler = MessageHandler.parseMessage( message, clientSocket );
            
            client = handler.getClient();
            user   = handler.getUser();
            
            connection.setIsUpdateConnection( message.isUpdateConnection() ); 
            
            client.addConnection( connection );
            
            // Main message loop
            while ( clientSocket.getSocket().isConnected() )
            {
                MessageHandler.handleMessage( handler, clientSocket );
                
                message = (ActionMessage) in.readObject();
                
                handler = MessageHandler.parseMessage( message, clientSocket );
            }
        }
        catch ( CloseConnectionException e )
        {
            Log.writeEntry( "CloseConnectionException: " + e.getMessage() );
            closeSocket();
        }
        catch ( MessageException e )
        {
            Log.writeEntry( "MessageException: " + e.getMessage() );
            e.printStackTrace();
            closeSocket();
        }
        catch ( IOException e )
        {
            Log.writeEntry( "IOException: " + e.getMessage() );
            e.printStackTrace();
            closeSocket();
        }
        catch ( ClassNotFoundException e )
        {
            Log.writeEntry( "ClassNotFoundException: " + e.getMessage() );
            e.printStackTrace();
            closeSocket();
        }
        finally
        {
            closeSocket();
        }
    }
            
    /**
     * Clean up this connection
     */
    private void closeSocket()
    {
        try
        {
            if ( clientSocket != null && !clientSocket.isClosed() )
                clientSocket.close();
        }
        catch( IOException e )
        {

        }
        finally
        {
            // This will remove the connection from the client
            if ( connection != null && connection.isConnected() )
            {
                connection.disconnect();
                
                if ( DEBUG )
                    Log.writeEntry( "disconnected client: " + connection.toString() );
            }
        }
    }
}